package com.xmqsfsky1017.skysrf.utils.tree;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.xmqsfsky1017.skysrf.utils.tree.WeakerTree.TreeDieException; // 保留隔壁的异常引用
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.stream.Collectors;

public class StrongerTree {
    private String value;
    private StrongerTree mom;
    private final Map<String, StrongerTree> sons = new HashMap<>(); // 修复泛型
    private final Set<String> fruits = new HashSet<>(); // 修复泛型

    public StrongerTree(String value) {
        this(value, null);
    }

    public StrongerTree(String value, StrongerTree mom) {
        this.value = value;
        this.mom = mom;
    }

    public StrongerTree getOrCreate(String path) {
        if (path == null || path.isEmpty() || "/".equals(path)) {
            return this;
        }
        StrongerTree current = this;
        String[] parts = path.split("/");
        for (String part : parts) {
            if (part.isEmpty()) continue;
            current.sons.putIfAbsent(part, new StrongerTree(part, current));
            current = current.sons.get(part);
        }
        return current;
    }

    public void grow(String path, String fruit) throws TreeDieException {
        if (fruit == null) {
            throw new TreeDieException("果实编码不能为null");
        }
        getOrCreate(path).fruits.add(fruit);
    }

    public void remove(String road) {
        remove(road, null);
    }

    public void remove(String road, String value) {
        if (!isExist(road)) return;
        
        StrongerTree target = getOrCreate(road);
        if (value == null) {
            target.sons.clear();
            target.fruits.clear();
        } else {
            target.fruits.remove(value);
            target.sons.entrySet().removeIf(entry -> 
                value.equals(entry.getKey())
            );
        }
    }

    public List<StrongerTree> findAllFruit(String road) { // 修复泛型
        List<StrongerTree> result = new ArrayList<>(); // 修复泛型
        if (!isExist(road)) return result;
        
        Deque<StrongerTree> stack = new ArrayDeque<>(); // 修复泛型
        stack.push(getOrCreate(road));
        
        while (!stack.isEmpty()) {
            StrongerTree node = stack.pop();
            if (!node.fruits.isEmpty()) {
                result.add(node);
            }
            for (StrongerTree son : node.sons.values()) {
                stack.push(son);
            }
        }
        return result;
    }

    public boolean isExist(String road) {
        if (road == null || road.isEmpty() || "/".equals(road)) return true;
        
        StrongerTree current = this;
        String[] parts = road.split("/");
        for (String part : parts) {
            if (part.isEmpty()) continue;
            if (!current.sons.containsKey(part)) {
                return false;
            }
            current = current.sons.get(part);
        }
        return true;
    }

    public List<String> checkCode(String fruitValue) { // 修复泛型
        return findAllFruit("/").stream()
                .filter(p -> p.fruits.contains(fruitValue))
                .map(this::getPath)
                .collect(Collectors.toList());
    }

    public Map<String, List<String>> buildIndex() {
        Map<String, List<String>> index = new HashMap<>();
        for (StrongerTree node : this.findAllFruit("/")) {
            String path = getPath(node);
            for (String fruit : node.fruits) {
                index.computeIfAbsent(fruit, k -> new ArrayList<>()).add(path);
            }
        }
        return index;
    }

    private String getPath(StrongerTree node) {
        LinkedList<String> path = new LinkedList<>(); // 修复泛型
        StrongerTree current = node;
        while (current != null && current.mom != null) {
            path.addFirst(current.value);
            current = current.mom;
        }
        return String.join("/", path);
    }

    public String toXml() {
        return toXml("", this);
    }

    private String toXml(String indent, StrongerTree node) {
        StringBuilder sb = new StringBuilder();
        String attrs = "value='" + node.value + "'";
        
        if (!node.fruits.isEmpty()) {
            String fruits = String.join(",", node.fruits);
            attrs += " fruit='" + fruits + "'";
        }
        
        if (node.sons.isEmpty()) {
            sb.append(indent).append("<node ").append(attrs).append("/>\n"); // 修复XML标签
        } else {
            sb.append(indent).append("<node ").append(attrs).append(">\n"); // 修复XML标签
            node.sons.values().stream()
                .sorted(Comparator.comparing(p -> p.value))
                .forEach(son -> sb.append(toXml(indent + "    ", son)));
            sb.append(indent).append("</node>\n"); // 修复XML标签
        }
        return sb.toString();
    }

    @Override
    public String toString() {
        return toXml().trim();
    }

    public static StrongerTree load(String xmlString) throws TreeDieException { // 用隔壁的异常
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new ByteArrayInputStream(xmlString.getBytes()));
            return parseNode(doc.getDocumentElement(), null);
        } catch (Exception e) {
            throw new TreeDieException("XML解析失败: " + e.getMessage());
        }
    }

    private static StrongerTree parseNode(Element elem, StrongerTree parent) {
        String value = elem.getAttribute("value");
        StrongerTree node = new StrongerTree(value, parent);
        
        if (elem.hasAttribute("fruit")) {
            String fruits = elem.getAttribute("fruit");
            if (!fruits.isEmpty()) {
                String[] fruitArray = fruits.split(",");
                for (String fruit : fruitArray) {
                    if (!fruit.isEmpty()) {
                        node.fruits.add(fruit);
                    }
                }
            }
        }
        
        NodeList children = elem.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) { // 修复常量名
                Element childElem = (Element) child;
                StrongerTree childNode = parseNode(childElem, node);
                node.sons.put(childNode.value, childNode);
            }
        }
        return node;
    }
}
